#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
#include <ctime>
#include <algorithm>
#include <cassert>
using namespace std;

// 提交
// #define UPLOAD

#define TEST

// 服务器信息
unordered_map<string,vector<int>> serverInfos; // A:内核，内存  B:  ID: 1 
// 虚拟机信息
unordered_map<string,vector<int>> vmInfos;   // 内核，内存，部署到？服务器，
// 已经部署的虚拟机
unordered_map<string,vector<int>> own_vmInfos; 

// 请求信息
vector<vector<string>> requestInfos;
vector<vector<vector<string>>> requestInfos_vec;

// 购买的服务器信息
int serverNumber = 0;
unordered_map<int,vector<int>> sysServerResource;  // 

// 当前开机服务器
vector<int> serverRunVms;                          //
// 记录虚拟机运行在那个服务器上
unordered_map<string,vector<int>> vmOnServer;      //

vector<string> res;

#ifdef TEST
    const string filePath = "../../training-data/training-2.txt";
#endif
// 成本
long long SERVERCOST = 0,POWERCOST=0,TOTALCOST =0;

// 按照服务器A点内存降序排序
// std::sort(serverInfos.begin(),serverInfos.end(),cmpServerMemoryDown)
// 按照服务器A点内存升序排序
//bool cmpServerMemoryUp(const Server &server1, const Server &server2)
//{
//    return server1.memoryA>server2.memoryA;
//}

string maxcpu_serverType = " ", maxmem_serverType = " ";
int max__cpuCores = 0, max__memorySize = 0;
int sum_cpu = 0, sum_mem = 0, max_cpu = 0, max_mem = 0;
int cMorem = 0, mMorec = 0;

void generateServer(string &serverType,string &cpuCores,string &memorySize,string &serverCost,string &powerCost){
    string _serverType="";
    
    for(int i =1;i<serverType.size() -1;i++){
        _serverType += serverType[i];
    }
    int _cpuCores =0,_memorySize=0,_serverCost=0,_powerCost=0;

    for(int i=0;i<cpuCores.size() -1;i++){
        _cpuCores = 10*_cpuCores + cpuCores[i] - '0';
    }
    for(int i=0;i<memorySize.size() -1;i++){
        _memorySize = 10*_memorySize + memorySize[i] - '0';
    }
    for(int i=0;i<serverCost.size() -1;i++){
        _serverCost = 10*_serverCost + serverCost[i] - '0';
    }
    for(int i=0;i<powerCost.size()-1;i++){
        _powerCost = 10*_powerCost + powerCost[i] - '0';
    }
    if(_cpuCores >= max__cpuCores)
    {
        if(_cpuCores == max__cpuCores)
        {
            if(serverInfos[_serverType][3] > serverInfos[maxcpu_serverType][3])
            {
                maxcpu_serverType = _serverType;
            }
        }
        else
        {
            maxcpu_serverType = _serverType;
        }
        max__cpuCores = _cpuCores;
    }

    if(_memorySize >= max__memorySize)
    {
        
        if(_memorySize == max__memorySize)
        {
            if(serverInfos[_serverType][3] > serverInfos[maxmem_serverType][3])
            {
                maxmem_serverType = _serverType;
            }
        }
        else
        {
            maxmem_serverType = _serverType;
        }
        max__memorySize = _memorySize;
    }
#ifdef TEST
    // cout << _serverType <<'\t' << (float)_cpuCores/(float)_memorySize <<'\t' << endl;
#endif
    serverInfos[_serverType] = vector<int>{_cpuCores/2 ,_cpuCores/2,_memorySize/2,_memorySize/2,_serverCost,_powerCost};
}

int core_max = 0, mem_max= 0;

void generateVm(string &vmType,string &vmCpuCores,string &vmMemory,string &vmTwoNodes){
    string _vmType;

    for(int i=1;i<vmType.size() -1;i++){
        _vmType += vmType[i];
    }

    int _vmCpuCores = 0,_vmMemory=0,_vmTwoNodes=0;
    for(int i=0;i<vmCpuCores.size()-1;i++){
        _vmCpuCores = _vmCpuCores*10 + vmCpuCores[i] - '0';
    }

    for(int i=0;i<vmMemory.size()-1;i++){
        _vmMemory = _vmMemory*10 + vmMemory[i] - '0';
    }
    
    /* 获得虚拟机最大内存和最大内核*/
    core_max = _vmCpuCores > core_max ? _vmCpuCores : core_max;
    mem_max = _vmMemory > mem_max ? _vmMemory : mem_max;

    _vmTwoNodes = vmTwoNodes[0] == '1' ? 1: 0;

    vmInfos[_vmType] = vector<int>{_vmCpuCores,_vmMemory,_vmTwoNodes};
}

/* 
    编写者：Mr.zhang 

    函数作用：获取合适的服务器型号.

    形参：无。

    返回值：<消耗低的服务器，资源大的服务器>.
*/
vector<string> getServer()
{
    vector<string> serType = {"", ""};

    /* ser -> <>*/
    int max = 0, min_pow = 10000;
    float rat = (float)sum_cpu / (float)sum_mem;
    float rat_max = 1000;
    for(auto ser : serverInfos){
        int _cpu = ser.second[0] * 2;
        int _mem = ser.second[2] * 2;
        int _powerCost = ser.second[5];
        if(_cpu > core_max && _mem > mem_max && (float)_cpu/(float)_mem == 1.0) 
        // if(_cpu > core_max && _mem > mem_max && abs(rat - (float)_cpu/(float)_mem) < rat_max) 
        {
            rat_max = abs(rat - (float)_cpu/(float)_mem);
            if(_cpu > max)
            {
                serType[0] = ser.first;
                max = _cpu;
            }
            if(_powerCost < min_pow)
            {
                serType[1] = ser.first;
                min_pow = _powerCost;
            }

        }
    }

    return serType;
}

// 解析用户添加请求
void generateRequest(string &op,string &reqVmType,string &reqId){

    string _op,_reqVmType,_reqId;
    _op = op.substr(1,op.size() -1);
    _reqVmType = reqVmType.substr(0,reqVmType.size() -1);
    _reqId = reqId.substr(0,reqId.size() -1);

    sum_cpu += vmInfos[_reqVmType][0];
    sum_mem += vmInfos[_reqVmType][1];
    if(sum_cpu > max_cpu)
        max_cpu = sum_cpu;
    if(sum_mem > max_mem)
        max_mem = sum_mem;

    if(vmInfos[_reqVmType][0] >= vmInfos[_reqVmType][1])
        cMorem += 1;
    else 
        mMorec += 1;
        // mMorec += vmInfos[_reqVmType][1];

    own_vmInfos[_reqId] = vector<int>{vmInfos[_reqVmType][0], vmInfos[_reqVmType][1]};
    
    requestInfos.push_back(vector<string>{_op,_reqVmType,_reqId});
}

// 解析用户删除请求
void generateRequest(string &op,string &reqId){
    string _op,_reqId;
    _reqId = reqId.substr(0,reqId.size() -1);
    _op = op.substr(1,op.size() -1);

    sum_cpu -= (own_vmInfos[_reqId][0]/1.08);
    sum_mem -= (own_vmInfos[_reqId][1]/1.08);

    requestInfos.push_back(vector<string>{_op,_reqId});
}

// 尝试在服务器上分配虚拟机资源
bool choseServer(vector<int> &server,vector<int> &vm,int serverId,string vmId){
    int vmCores = vm[0],vmMemory = vm[1],vmTwoNodes = vm[2];
    int &serverCoreA = server[0],&serverCoreB = server[1],&serverMemoryA = server[2],&serverMemoryB = server[3];
    if(vmTwoNodes){
        int needCores = vmCores/2,needMemory = vmMemory/2;
        if(serverCoreA >= needCores && serverCoreB >=needCores && serverMemoryA >= needMemory && serverMemoryB >= needMemory){
            serverCoreA -= needCores;
            serverCoreB -= needCores;
            serverMemoryA -= needMemory;
            serverMemoryB -= needMemory;
            vmOnServer[vmId] = vector<int>{serverId,vmCores,vmMemory,1,2};
            res.push_back("("+to_string(serverId)+")\n");
            return true;
        }
        else{
            return false;
        }
    }
    else if(serverCoreA >= vmCores && serverMemoryA >= vmMemory){
        serverCoreA -= vmCores;
        serverMemoryA -= vmMemory;
        vmOnServer[vmId] = vector<int>{serverId,vmCores,vmMemory,1};
        res.push_back("("+to_string(serverId)+", A)\n");
        return true;
    }
    else if(serverCoreB >= vmCores && serverMemoryB >= vmMemory){
        serverCoreB -= vmCores;
        serverMemoryB -= vmMemory;
        vmOnServer[vmId] = vector<int>{serverId,vmCores,vmMemory,2};
        res.push_back("("+to_string(serverId)+", B)\n");
        return true;
    }
    
    return false;
}


// 处理创建虚拟机操作
// for(auto req:requestInfos_vec[day])  req = createVmInfo = vector<string>{_op,_reqVmType,_reqId}
int createVM(vector<string> &createVmInfo){
    string _reqVmType = createVmInfo[1],_reqId = createVmInfo[2];

    // 
    vector<int> vm = vmInfos[_reqVmType];
    int success = -1;
    for(int i=0;i<serverNumber;i++){
        auto &server = sysServerResource[i];
        if(choseServer(server,vm,i,_reqId)) {
            serverRunVms[i]++;
            success = 1;
            break;
        }
        assert(server[0]>=0 && server[1]>=0 && server[2]>=0 && server[3]>=0);
    }
    return success;
}

// 处理删除虚拟机操作
void delVM(vector<string> &delVmInfo){
    string _vmId = delVmInfo[1];
    // vmOnServer[vmId] = vector<int>{serverId,vmCores,vmMemory,1};
    // 
    // vmOnServer[vmId] = vector<int>{serverId,vmCores,vmMemory,1,2};
    vector<int> _vmInfo = vmOnServer[_vmId]; 
    int _serverId = _vmInfo[0];

    // 
    serverRunVms[_serverId]--;

    vector<int> &server = sysServerResource[_serverId];
    if(_vmInfo.size() == 5){
        int cores = _vmInfo[1]/2,memory = _vmInfo[2]/2;
        server[0] += cores;
        server[1] += cores;
        server[2] += memory;
        server[3] += memory;
    }
    else{
        int cores = _vmInfo[1],memory = _vmInfo[2];
        if(_vmInfo[3] == 1){
            server[0] += cores;
            server[2] += memory;
        }else{
            server[1] += cores;
            server[3] += memory;
        }
    }
}

// 初始化server，如何初始化购买的服务器是一个大的优化
void bugServer(){
    vector<string> serVer = getServer();
    string serverType = serVer[1];
    int cpu_low = sum_cpu/2, mem_low = sum_mem/2;
    sum_mem -= mem_low;
    sum_cpu -= cpu_low;
    int low_n = max((cpu_low / (serverInfos[serVer[1]][0]*2)),(mem_low / (serverInfos[serVer[1]][2]*2))) + 1;
    int high_n = max((sum_cpu / (serverInfos[serVer[0]][0]*2) + 1),(sum_mem / (serverInfos[serVer[0]][2]*2))) + 10;
    
    int n = low_n + high_n;
#ifdef TEST
    cout << n << '\t' << low_n << '\t'<< high_n << '\t' << serVer[0] <<'\t' << serVer[1] << endl;
#endif
    serverRunVms.resize(n,0);
    string initBuy = "(purchase, ";
    initBuy += to_string(2)+")\n";

    res.push_back(initBuy);

    string pauseInfo ="("+serverType+", ";
    pauseInfo+= std::to_string(low_n)+")\n";

    res.push_back(pauseInfo);
    
    for(int i=0;i < low_n;i++){
        sysServerResource[serverNumber++] = serverInfos[serverType];
        SERVERCOST += serverInfos[serverType][4];
    }
    serverType = serVer[0];
    pauseInfo ="("+serverType+", ";
    pauseInfo+= std::to_string(high_n)+")\n";

    res.push_back(pauseInfo);

    for(int i=0;i<high_n;i++){
        sysServerResource[serverNumber++] = serverInfos[serverType];
        SERVERCOST += serverInfos[serverType][4];
    }
#ifdef TEST
    int ser_core = 0, ser_mem = 0;
    for(int i=0;i < low_n;i++){
        ser_core += serverInfos[serVer[1]][0]*2;
        ser_mem += serverInfos[serVer[1]][2]*2;
    }
    for(int i=0;i < high_n;i++){
        ser_core += serverInfos[serVer[0]][0]*2;
        ser_mem += serverInfos[serVer[0]][2]*2;
    }

    cout << sum_cpu + cpu_low<< '\t'<< sum_mem + mem_low<< endl;
    cout << ser_core << '\t' << ser_mem <<endl;
#endif
}

// 扩容服务器策略
void expansion(){
    string s = "(purchase, 0)\n";

    res.push_back(s);
}

// 迁移虚拟机策略
void migrate(){
    string s = "(migration, 0)\n";

    res.push_back(s);
}

// 分配策略
void match(int day){
    if(day!=0) expansion();
    migrate();
    // printf("There are %d requests waiting to matching !!\n",requestInfos.size());
    for(auto req:requestInfos_vec[day]){
        // 创建虚拟机 还是 删除虚拟机
        int opType = req.size() == 3 ? 1:0;
        if(opType){
            int resourceEnough = createVM(req);
            assert(resourceEnough != -1);
        }
        else{
            // 修复删除虚拟机bug
            delVM(req);
        }
    }
}

void serverPower(){
    for(int i=0;i<serverNumber;i++){
        if(serverRunVms[i] != 0){
            POWERCOST += sysServerResource[i][5];
        }
    }
}

/* 
    @author：Mr.zhang 

    @function：获取每日虚拟机的需求信息.

    @param：当日的虚拟机向量表 vmData[i] = <虚拟机动作，虚拟机型号，虚拟机id>.

    @return：<当日最大核心数，当日最大内存数，当日核心总数，当日内存总数>.
*/
vector<int> get_dayVmInfo(vector<vector<string>> vmData)
{
    vector<int> vmDay_info;
    string _vmType, _vmId;
    int coreSum = 0,memSum = 0, coreMax = 0, memMax = 0, coreSum_max = 0, memSum_max = 0;
    static int day = 0;

    for(auto data:vmData)
    {
        string _op = data[0];
        if(_op[0] == 'a')
        {
            _vmType = data[1];
            int coreNum = vmInfos[_vmType][0];
            int memNum = vmInfos[_vmType][1];
            coreSum += coreNum;
            coreSum_max = coreSum_max < coreSum ? coreSum : coreSum_max;
            memSum += memNum;
            memSum_max = memSum_max < memSum ? memSum : memSum_max;
            
            coreMax = coreNum > coreMax ? coreNum : coreMax;
            memMax = memNum > memMax ? memNum : memMax;
        }
        else if(_op[0] == 'd')
        {
            _vmId = data[1];
            int coreNum = vmOnServer[_vmId][1];
            int memNum = vmOnServer[_vmId][2];
            coreSum -= coreNum;
            memSum -= memNum;
        }
    }
    vmDay_info = {coreMax, memMax, coreSum_max, memSum_max};
#ifdef TEST
    // cout << vmDay_info[2] <<'\t' << vmDay_info[3] << '\t' << endl;
#endif
    return vmDay_info;
}

int cpu_get = 0, mem_get = 0;
/* 
    @author：Mr.zhang 

    @function：获取每天合适的服务器型号.

    @param：<当日最大核心数，当日最大内存数，当日核心总数，当日内存总数>。

    @return：<消耗低的服务器，资源大的服务器>.
*/
string get_dayServer(vector<vector<string>> vmData)
{
    vector<int> vmDay_info;
    vmDay_info = get_dayVmInfo(vmData);

    string serType = "";
    vector<int> _server = {0, 0};
    /* ser -> <>*/
    if(serverNumber > 1){
        for(int i = serverNumber - 2; i < serverNumber; ++i){
            _server[0] += sysServerResource[i][0] * 2;
            _server[1] += sysServerResource[i][2] * 2;
        }
    }
    cpu_get = vmDay_info[2] - _server[0];
    mem_get = vmDay_info[3] - _server[1];

    float get_rat = (float)cpu_get / (float)mem_get;

    int max = 0, min = 10000;
    float min_ratCmb = 1000;
    for(auto ser : serverInfos){
        int _cpu = ser.second[0] * 2;
        int _mem = ser.second[2] * 2;
        float rat = (float)_cpu/((float)_mem);
        if(get_rat > 0){
            float ratCmb = abs(get_rat - rat);
            if(min_ratCmb > ratCmb)
            {
                min_ratCmb = ratCmb;
                serType = ser.first;
            }
        }
        else{
            if(cpu_get < 0 && min > rat){
                min = rat;
                serType = ser.first;
            }else if(mem_get < 0 && max < rat){
                max = rat;
                serType = ser.first;
            }
        }
    }
    
#ifdef TEST
    cout << cpu_get << '\t' << mem_get<< '\t' << serType << endl;
    cout << serverInfos[serType][0]*2 << '\t' << serverInfos[serType][2]*2 << endl;
#endif
    return serType;
}

/* 
    @function：计算购买信息

    @param：当日的虚拟机向量表.
*/
void day_purchase(vector<vector<string>> data)
{
    string s;
    /*1. 获取当日虚拟机需求信息*/
    /*2. <当日最大核心数，当日最大内存数，当日核心总数，当日内存总数>*/
    string serverType;
    serverType = get_dayServer(data);
    int n = 0;
    if(cpu_get < 0 && mem_get < 0)
    {
        // n = max((cpu_get / (serverInfos[serverType][0]*2)),(mem_get / (serverInfos[serverType][2]*2))); 
        n = 0;
    }
    else{
        n = max((cpu_get / (serverInfos[serverType][0]*2)),(mem_get / (serverInfos[serverType][2]*2)) + 2);    
    }
    // cout << serverType <<'\t' << endl;
    for(int i = 0; i < n; ++i)
        serverRunVms.push_back(0);
    
    string initBuy = "(purchase, ";
    initBuy += to_string(1)+")\n";

    res.push_back(initBuy);

    string pauseInfo ="("+serverType+", ";
    pauseInfo+= std::to_string(n)+")\n";

    res.push_back(pauseInfo);
    
    for(int j = 0;j < n; j++){
        sysServerResource[serverNumber++] = serverInfos[serverType];
        SERVERCOST += serverInfos[serverType][4];
    }
    
#ifdef TEST
    // for(auto val : vmDay_info) cout << val << '\t';
    // cout << endl;
    cout << serverInfos[serverType][0]*2 * n << '\t' << serverInfos[serverType][2]*2 * n << endl;
    cout << serverType <<'\t' << n << '\t' << endl;
#endif


}

int main() {
    clock_t start, finish;
    start = clock();
#ifdef TEST
    std::freopen(filePath.c_str(),"rb",stdin);
#endif
    int serverNum;
    string serverType,cpuCores,memorySize,serverCost,powerCost;
    scanf("%d",&serverNum);

    for(int i =0;i<serverNum;i++){
        cin>>serverType>>cpuCores>>memorySize>>serverCost>>powerCost;
        generateServer(serverType,cpuCores,memorySize,serverCost,powerCost);
    }

    int vmNumber = 0;
    scanf("%d",&vmNumber);

    string vmType,vmCpuCores,vmMemory,vmTwoNodes;
    for(int i =0;i<vmNumber;i++){
        cin>>vmType>>vmCpuCores>>vmMemory>>vmTwoNodes;
        generateVm(vmType,vmCpuCores,vmMemory,vmTwoNodes);
    }

    int requestdays = 0,dayRequestNumber = 0;
    scanf("%d",&requestdays);
    string op,reqVmType,reqId;

    // 开始处理请求
    
    for(int day=0;day<requestdays;day++){
        scanf("%d",&dayRequestNumber);
        requestInfos.clear();
        for(int i =0;i<dayRequestNumber;i++){
            cin>>op;
            if(op[1] == 'a'){
                cin>>reqVmType>>reqId;
                generateRequest(op,reqVmType,reqId);
            }else{
                cin>>reqId;
                generateRequest(op,reqId);
            }
        }
        requestInfos_vec.push_back(requestInfos);
    }

    // bugServer();
#ifdef TEST
    
#endif
    for(int day=0;day<requestdays;day++){
        // day_purchase(requestInfos_vec[day]);
#ifdef TEST
    day_purchase(requestInfos_vec[day]);
#endif
        

#ifdef TEST
        if(day == 0 || (day+1)%100 == 0){
            printf("The %d day begin matching!!!\n",day+1);
        }
#endif
        match(day);
        serverPower();
    }

#ifdef UPLOAD
    for (auto &s:res) std::cout<<s;
#endif
#ifdef TEST

    fclose(stdin);
    finish = clock();
    TOTALCOST = SERVERCOST + POWERCOST;

    printf("\nusr time: %f s \n",double(finish - start) / CLOCKS_PER_SEC);
    printf("server cost: %lld \npower cost: %lld \ntotal cost: %lld \n",SERVERCOST,POWERCOST,TOTALCOST);
#endif

    return 0;
}